package org.example.order.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;

/**
 * Description: RabbitConfig配置文件
 * Author: e
 * CreateDate: 2021-08-02
 */
@Configuration
public class RabbitConfig {


     /**
     * 设置消息转换器，用于将对象转换成JSON数据
     * 可以通过converterAndSend将对象发送消息队列
     * 监听器也可以通过该工具将接受对象反序列化成java对象
     * @return Jackson转换器
     */
    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }

    /**
     * 订单队列
     * @return
     */
    @Bean
    public Queue queue(){
        Map<String,Object> props =  new HashMap<>();
        //消息的生存时间10秒
        props.put("x-message-ttl",10000);
        //设置该队列所关联的死信交换机，当队列消息ttl到期后没有消费，则加入死信队列
        props.put("x-dead-letter-exchange","ex.order.dlx");
        //设置该队列所关联的死信交换机 routingkey ，如果没有特殊指定，使用原理队列的routingkey
        props.put("x-dead-letter-routing-key","order.key.dlx");
        return new Queue(
                //队列名称
                "q.order",
                //是否持久
                true,
                //是否独有
                false,
                //是否自动删除
                false,
                props
        );
    }

    /**
     * 订单死信队列（用于取消用户订单）
     * @return
     */
    @Bean
    public Queue queueDlx(){
        return new Queue(
                //队列名称
                "q.order.dlx",
                //是否持久
                true,
                //是否独有
                false,
                //是否自动删除
                false);
    }

    /**
     * 订单交换机
     * @return
     */
    @Bean
    public Exchange exchange(){
        return new DirectExchange(
                //交换机名称
                "ex.order",
                //是否持久
                true,
                //是否独有
                false,
                //是否自动删除
                null
        );
    }


    /**
     * 订单死信交换机
     * @return
     */
    @Bean
    public Exchange exchangeDlx(){
        return new DirectExchange(
                "ex.order.dlx",
                true,
                false,
                null
        );
    }

    /**
     * 绑定队列
     * @return
     */
    @Bean
    public Binding binding(){
        return BindingBuilder
                //队列
                .bind(queue())
                //交换机
                .to(exchange())
                //routingKey
                .with("order.key")
                .noargs();
    }

    /**
     * 死信绑定队列
     * @return
     */
    @Bean
    public Binding bindingDlx(){
        return BindingBuilder
                //死信队列
                .bind(queueDlx())
                //死信交换机
                .to(exchangeDlx())
                //routingKey
                .with("order.key.dlx")
                .noargs();
    }
}
